home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_10_03
/
1003088a
< prev
next >
Wrap
Text File
|
1992-01-11
|
12KB
|
454 lines
/************************************************************
* Program: CMENU Menu Compiler
* Module: cmenu1.c
* Menu Compiler:
* Main and Utility Functions
* Written by: Leor Zolman, 7/91
************************************************************/
#define MASTER
#include "cmenu.h"
#include "ccmenu.h"
#include <string.h>
#if __STDC__
# include <stdarg.h>
#else
# include <varargs.h>
#endif
int main(argc,argv)
int argc;
char **argv;
{
register i;
printf("CMENU Menu Compiler v%s\n", VERSION);
if (argc < 2)
{
puts("usage: cmenu <menu-source-file(s)>\n");
return 0;
}
for (i = 1; i < argc; i++)
if (dofile(argv[i]) == ERROR) /* process source files */
return 1;
return 0;
}
/************************************************************
* dofile():
* Process a single .mnu source file
************************************************************/
int dofile(name)
char *name;
{
register i;
char *cp;
if ((cp = strstr(name, ".mnu")) ||
(cp = strstr(name, ".MNU")))
*cp = '\0';
strcpy(src_name, name);
strcat(src_name, ".mnu");
strcpy(obj_name, name);
if ((fp = fopen(src_name, "r")) == NULL)
return fprintf(stderr, "Can't open %s\n", src_name);
n_menus = 0;
lineno = 1;
in_menu = FALSE;
fatal = FALSE;
/* Main processing loop. Read a token and process it,
* until end of file is reached:
*/
while ((token = gettok(fp)) != T_EOF)
{
if (!in_menu && token != T_MENU)
{
error("Each menu must begin with the Menu keyword");
break;
}
if ((*keywords[token].t_func)() == ERROR)
if (fatal) /* If fatal error, exit loop */
break;
}
fclose(fp);
if (!n_menus)
return error("No menus defined");
if (in_menu)
{
if (n_items)
itemcheck();
error("Menu definition missing \"Endmenu\" statement");
}
for (i = 0; i < n_menus; i++) /* check for undefined */
if (!MInfo[i].Processed) /* "lmenu" references */
{
printf("Local Menu \"%s\" is undefined.\n",
MInfo[i].Name);
err_flag = TRUE;
}
if (err_flag)
return ERROR;
if (write_file() == ERROR)
return ERROR;
return OK;
}
/************************************************************
* create_menu():
* Construct a new menu information structure and
* return it (by value).
* Set fatal to TRUE if can't create.
************************************************************/
MINFO create_menu(name)
char *name;
{
MINFO mi;
if (n_menus == MAX_MENUS)
fatalerr("Maximum # of menus (%d) exceeded", MAX_MENUS);
else
{
strcpy(mi.Name, name);
mi.Processed = FALSE;
}
return mi;
}
/************************************************************
* find_menu():
* Search the Menu Info table for a named local menu.
* If found:
* Return a pointer to the entry if found, and set
* global variable menu_num to the menu's index
* else:
* return NULL
************************************************************/
MINFO *find_menu(name)
char *name;
{
int i;
for (i = 0; i < n_menus; i++)
if (!strcmp(MInfo[i].Name, name))
{
menu_num = i;
return &MInfo[i];
}
return NULL;
}
/************************************************************
* create_item(): Allocate space for Item Info structure,
* Initialize it and return a pointer to the structure
* Return NULL if there was a creation error.
************************************************************/
IINFO *create_item(name)
char *name;
{
IINFO *IIp;
ITEM *Ip;
if (n_items == MAX_ITEMS)
{
fatalerr("Max. # of items (%d) exceeded", MAX_ITEMS);
return NULL;
}
if ((IIp = (IINFO *) malloc(sizeof(IINFO))) == NULL)
{
fatalerr("Out of memory");
return NULL;
}
strcpy(IIp->Name, name);
Ip = &IIp->Item;
Ip->acttyp = ACT_NONE;
Ip->pre_clear = Ip->post_clear = Ip->prompt = DEFAULT;
Ip->nextcode = DEFAULT;
Ip->nextitem = Ip->lmenunum = 0;
*Ip->text = *Ip->path = *Ip->action = *Ip->help = '\0';
return IIp;
}
/************************************************************
* find_item():
* Search the Item Info table for a named item in the
* currently active menu definition.
* If item name found:
* Set item_num to the index value of the Item,
* Return a pointer to the entry
* else:
* return NULL
************************************************************/
IINFO *find_item(name)
char *name;
{
int i;
for (i = 0; i < n_items; i++)
if (!strcmp(MIp->Items[i]->Name, name))
{
item_num = i;
return MIp->Items[i];
}
return NULL;
}
/************************************************************
* itemcheck():
* Check the currently active item to make sure
* both a Text and an Action clause have been
* explicitly given.
************************************************************/
Void itemcheck()
{
if (!*Ip->text)
error("No TEXT clause found for current item");
if (Ip->acttyp == ACT_NONE)
error("No ACTION clause found for current item");
}
/************************************************************
* write_file():
* Write menu object file to disk, ready for
* execution via rmenu.
* Menu object file format:
* --------------------------------
* <count> (integer count of # of menus in file)
* MENU 1 (MENU structure for 1st Menu)
* ITEM 1
* ITEM 2
* ...
* ITEM n_items
* MENU 2 (MENU structure for 2nd Menu)
* ...
* .
* .
* .
* MENU <count> (MENU structure for final Menu)
* ...
* --------------------------------
*
************************************************************/
int write_file()
{
int i,j;
strcat(obj_name, ".mnc");
if ((fp = fopen(obj_name, "wb")) == NULL)
{
fprintf(stderr,
"Cannot open %s for writing.\n", obj_name);
return ERROR;
}
if (fwrite((Void *)&n_menus, sizeof n_menus, 1, fp) != 1)
{
fprintf(stderr,
"Error writing menu count to %s\n", obj_name);
return ERROR;
}
for (i = 0; i < n_menus; i++)
{
Mp = &MInfo[i].Menu;
if (fwrite((Void *) Mp, sizeof (MENU), 1, fp) != 1)
{
fprintf(stderr,
"Error writing to %s\n", obj_name);
return ERROR;
}
for (j = 0; j < Mp->nitems; j++)
{
if (fwrite((Void *) &MInfo[i].Items[j]->Item,
sizeof (ITEM), 1, fp) != 1)
{
fprintf(stderr,
"Error writing to %s\n", obj_name);
return ERROR;
}
free(MInfo[i].Items[j]);
}
}
printf("Menu object file %s written.\n", obj_name);
return OK;
}
/************************************************************
* warning():
* Display a warning message, preceded by source
* file name and line number, supporting format
* conversions.